package com.huifer.wgx.service.impl;

import com.huifer.wgx.model.InteriorLineEntity;
import com.huifer.wgx.model.InteriorPointEntity;
import com.huifer.wgx.model.ResultLineEntity;
import com.huifer.wgx.model.ResultPointEntity;
import com.huifer.wgx.repository.InteriorLineRepository;
import com.huifer.wgx.repository.InteriorPointRepository;
import com.huifer.wgx.repository.ResultLineRepository;
import com.huifer.wgx.repository.ResultPointRepository;
import com.huifer.wgx.service.ResultLineService;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import lombok.AllArgsConstructor;
import org.omg.PortableInterceptor.INACTIVE;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

/**
 * <p>Title : ResultLineServiceImpl </p>
 * <p>Description : </p>
 *
 * @author huifer
 * @date 2019-03-22
 */
@Service
public class ResultLineServiceImpl implements ResultLineService {

    @Autowired
    private ResultLineRepository resultLineRepository;
    @Autowired
    private InteriorLineRepository iLineRepository;
    @Autowired
    private ResultPointRepository resultPointRepository;

    /**
     * 将内业线段转换成成果线段
     *
     * @param workId 工作id
     * @param personnelId 内业人员id
     * @return 成果线段
     */
    @Override
    public List<ResultLineEntity> inter2ResultLine(Long workId, Long personnelId) {
        try {
            Specification<InteriorLineEntity> spec = (Specification<InteriorLineEntity>) (root, criteriaQuery, criteriaBuilder) -> criteriaBuilder
                    .and(
                            criteriaBuilder.equal(root.get("workId"), workId),
                            criteriaBuilder.equal(root.get("personnelId"), personnelId)
                    );

            List<InteriorLineEntity> inLine = iLineRepository.findAll(spec);

            Specification<ResultPointEntity> specP = (Specification<ResultPointEntity>) (root, criteriaQuery, criteriaBuilder) -> criteriaBuilder
                    .equal(
                            root.get("workId"), workId);
            List<ResultPointEntity> resultPointList = resultPointRepository.findAll(specP);

            List<ResultLineEntity> saveList = calcResultLine(inLine, workId, personnelId,
                    resultPointList);
            return resultLineRepository.saveAll(saveList);


        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    private List<ResultLineEntity> calcResultLine(List<InteriorLineEntity> inLine, Long workId,
            Long personnelId, List<ResultPointEntity> resultPointList) {
        try {
            // 需要和校验表关联比对 过滤 inLine
            List<ResultLineEntity> result = new ArrayList<>();
            for (int i = 0; i < inLine.size(); i++) {
                ResultLineEntity outLine = new ResultLineEntity();
                InteriorLineEntity inpLine = inLine.get(i);

                outLine.setResultLineStartPointName(inpLine.getInteriorLineStartPointName());
                outLine.setResultLineStartPointDeep(inpLine.getInteriorLineStartPointDeep());
                outLine.setResultLineEndPointName(inpLine.getInteriorLineEndPointName());
                outLine.setResultLineEndPointDeep(inpLine.getInteriorLineEndPointDeep());
                outLine.setResultLineType(inpLine.getInteriorLineType());

                // 关联关系
                outLine.setWorkId(workId);
                outLine.setPersonnelId(personnelId);
                setStartEndId(outLine, resultPointList);
                if (outLine.getResultLineEndPointId() == null
                        || outLine.getResultLineStartPointId() == null) {
                    continue;
                }
                result.add(outLine);
            }
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    private void setStartEndId(ResultLineEntity outLine, List<ResultPointEntity> resultPointList) {
        for (int i = 0; i < resultPointList.size(); i++) {
            ResultPointEntity inPoint = resultPointList.get(i);
            if (inPoint.getResultPointName()
                    .equals(outLine.getResultLineStartPointName())) {
                outLine.setResultLineStartPointId(inPoint.getResultPointId());
            } else if (inPoint.getResultPointName()
                    .equals(outLine.getResultLineEndPointName())) {
                outLine.setResultLineEndPointId(inPoint.getResultPointId());
            }
        }
    }

    /**
     * 保存成果线段
     *
     * @param iLine 成果线段
     * @return 成果线段
     */
    @Override
    public ResultLineEntity saveOne(ResultLineEntity iLine) {
        try {
            return resultLineRepository.save(iLine);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 跟新成果线段
     *
     * @param iLine 成果线段
     * @return 成果线段
     */
    @Override
    public ResultLineEntity updateiLine(ResultLineEntity iLine) {
        try {
            return resultLineRepository.save(iLine);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 查询所有
     *
     * @param pageNum 页面号
     * @param pageSize 页面大小
     * @return 成果线段
     */
    @Override
    public Page<ResultLineEntity> findAll(Integer pageNum, Integer pageSize) {
        try {
            return getResultLineEntity(pageNum, pageSize, null);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 根据工程id查询所有
     *
     * @param pageNum 页面号
     * @param pageSize 页面大小
     * @param workId 工程id
     * @return 成果线段结果
     */
    @Override
    public Page<ResultLineEntity> findByWorkId(Integer pageNum, Integer pageSize, Long workId) {
        try {
            Specification<ResultLineEntity> spec = (Specification<ResultLineEntity>) (root, criteriaQuery, criteriaBuilder) -> criteriaBuilder
                    .equal(root.get("workId"), workId);
            return getResultLineEntity(pageNum, pageSize, spec);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 根据内业人员id查询所有
     *
     * @param personnelId 内业id
     * @param pageNum 页面号
     * @param pageSize 页面大小
     * @return 成果线段结果
     */
    @Override
    public Page<ResultLineEntity> findByPersonnelId(Long personnelId, Integer pageNum,
            Integer pageSize) {
        try {
            Specification<ResultLineEntity> spec = (Specification<ResultLineEntity>) (root, criteriaQuery, criteriaBuilder) -> criteriaBuilder
                    .equal(root.get("personnelId"), personnelId);
            return getResultLineEntity(pageNum, pageSize, spec);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 获取全部成果点
     *
     * @param pageNum 页面号
     * @param pageSize 页面大小
     * @param spec 条件
     * @return 成果点
     */
    private Page<ResultLineEntity> getResultLineEntity(Integer pageNum, Integer pageSize,
            Specification<ResultLineEntity> spec) {
        Sort sort = new Sort(Direction.DESC, "resultLineId");
        Pageable pageable = PageRequest.of(pageNum - 1, pageSize, sort);
        return resultLineRepository.findAll(spec, pageable);
    }
}
